use std::collections::{HashMap, HashSet};
use crate::agent::{CognitiveAgent, AdvancedAgent};
use serde_json::Value;

/// 研究分析结果
#[derive(Debug, Clone)]
pub struct ResearchResult {
    pub key_insights: Vec<String>,
    pub related_concepts: HashMap<String, f32>, // 概念关联强度
    pub hypothesis: Vec<String>,
    pub data_sources: Vec<String>,
}

/// 研究引擎
pub struct ResearchEngine {
    knowledge_graph: HashMap<String, Vec<(String, f32)>>, // 概念 -> [(相关概念, 权重)]
    analysis_methods: Vec<Box<dyn AnalysisMethod>>,
}

impl ResearchEngine {
    pub fn new() -> Self {
        // 初始化基础知识图谱
        let mut knowledge_graph = HashMap::new();
        knowledge_graph.insert("market".to_string(), vec![
            ("trend".to_string(), 0.8),
            ("competition".to_string(), 0.7),
            ("regulation".to_string(), 0.6),
        ]);
        
        ResearchEngine {
            knowledge_graph,
            analysis_methods: vec![
                Box::new(SWOTAnalysis),
                Box::new(PESTAnalysis),
                Box::new(PorterFiveForces),
            ],
        }
    }

    /// 深度分析入口
    pub fn analyze(&self, keywords: &[String], agent: &mut AdvancedAgent) -> ResearchResult {
        // 认知预处理
        for keyword in keywords {
            agent.cognitive_agent.process_memory(
                &format!("Researching: {}", keyword),
                0.8
            );
        }

        // 多维度分析
        let mut result = ResearchResult {
            key_insights: Vec::new(),
            related_concepts: HashMap::new(),
            hypothesis: Vec::new(),
            data_sources: Vec::new(),
        };

        for method in &self.analysis_methods {
            method.apply(keywords, &mut result, &self.knowledge_graph);
        }

        // 知识图谱扩展
        self.expand_with_knowledge_graph(keywords, &mut result);

        result
    }

    fn expand_with_knowledge_graph(&self, keywords: &[String], result: &mut ResearchResult) {
        let mut visited = HashSet::new();
        let mut queue: Vec<&String> = keywords.iter().collect();

        while let Some(concept) = queue.pop() {
            if visited.contains(concept) {
                continue;
            }
            visited.insert(concept.clone());

            if let Some(related) = self.knowledge_graph.get(concept) {
                for (related_concept, weight) in related {
                    result.related_concepts
                        .entry(related_concept.clone())
                        .and_modify(|w| *w += weight)
                        .or_insert(*weight);

                    queue.push(related_concept);
                }
            }
        }
    }

    /// 添加自定义分析方法
    pub fn add_analysis_method(&mut self, method: Box<dyn AnalysisMethod>) {
        self.analysis_methods.push(method);
    }
}

/// 分析方法 trait
pub trait AnalysisMethod: Send + Sync {
    fn apply(&self, keywords: &[String], result: &mut ResearchResult, kg: &HashMap<String, Vec<(String, f32)>>);
}

/// SWOT 分析
struct SWOTAnalysis;
impl AnalysisMethod for SWOTAnalysis {
    fn apply(&self, keywords: &[String], result: &mut ResearchResult, _: &HashMap<String, Vec<(String, f32)>>) {
        result.key_insights.extend(
            keywords.iter().map(|k| format!("SWOT analysis for {}: potential strengths and weaknesses", k))
        );
        result.hypothesis.push("Emerging opportunities in related sectors".to_string());
    }
}

/// PEST 分析
struct PESTAnalysis;
impl AnalysisMethod for PESTAnalysis {
    fn apply(&self, keywords: &[String], result: &mut ResearchResult, _: &HashMap<String, Vec<(String, f32)>>) {
        result.key_insights.push(
            "Political and economic factors analysis".to_string()
        );
        result.data_sources.push("Government policy database".to_string());
    }
}

/// 波特五力模型
struct PorterFiveForces;
impl AnalysisMethod for PorterFiveForces {
    fn apply(&self, keywords: &[String], result: &mut ResearchResult, kg: &HashMap<String, Vec<(String, f32)>>) {
        let competition_level = keywords.iter()
            .filter_map(|k| kg.get(k))
            .flatten()
            .filter(|(rel, _)| rel == "competition")
            .map(|(_, w)| w)
            .sum::<f32>();

        result.key_insights.push(format!(
            "Industry competition level: {:.2}/1.0", competition_level
        ));
    }
}